import { defineComponent, h, ref, watchEffect, inject, computed, defineAsyncComponent } from 'vue'
import type { PropType, Ref } from 'vue'
import type { questionSideListState } from '@/types/baseConfig'
import questionOption from '@/basic/addEdit/questionsOption'
import pageStyle from '../../../styles/index.module.scss'
import FormItemDefault from './FormItemDefault'
import CommonDefault from './CommonDefault'
import ColDefault from './ColDefault'
import ShowParamsDefault from './ShowParamsDefault'
import CodeEdit from '@/components/nComponents/CodeEdit'
import { NCollapse, NCollapseItem } from 'naive-ui'
import { getDescInfo } from '@/enum/illustrateDesc'
import { deleteNestedProperty, getChilderParams, getRowValue, mergeParams } from '@/utils/dyForm'

export default defineComponent({
  name: 'CommentAll',
  props: {
    compData: {
      type: Object as PropType<questionSideListState>,
      default: () => {
        return {}
      }
    }
  },
  emits: ['save'],
  setup: function (props, { emit, slots }) {
    const $clone = inject('$clone') as <T>(data: T) => T
    const curren = inject('curren') as Ref<number[]>
    const info = ref<questionSideListState>(questionOption)
    watchEffect(() => {
      if (props.compData) {
        info.value = $clone(props.compData)
      }
    })
    /**
     *  代码编译器
     * */
    const editRef = ref()
    let oldType = ''
    const handSetting = (labelKey: string) => {
      oldType = labelKey
      const iluInfo = getDescInfo(labelKey)
      if (iluInfo) {
        const value = getRowValue(info.value, labelKey)
        iluInfo.value = value || null
        editRef.value.open(iluInfo)
      }
    }

    const codeChange = (e: any) => {
      if (e) {
        const labelKeyArr = oldType.split('.')
        const newParams = getChilderParams(labelKeyArr, 0, {}, e)
        info.value = mergeParams(info.value, newParams)
      } else {
        deleteNestedProperty(info.value, oldType)
      }
      handOptions()
    }

    //  说明
    const modules = import.meta.glob(['@/components/yFormData/illustrate/*.tsx'])
    const linkName = ref('')
    const AsyncComponent = computed(() => {
      const link: any = modules[`/src/components/yFormData/illustrate/${linkName.value}.tsx`]
      if (link) return defineAsyncComponent(link)
      return null
    })
    const descRef = ref()
    const handDesc = (e: any) => {
      if (linkName.value === e) {
        descRef.value.open()
      } else {
        linkName.value = e
      }
    }

    const handLoaded = () => {
      descRef.value.open()
    }
    /**
     *  变化回调
     * */
    let timer: any = null
    const handOptions = () => {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      timer = setTimeout(() => {
        handEmitSave()
      }, 450)
    }

    const handEmitSave = () => {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      emit('save', info.value)
    }

    const commonHeader = (title: string) => (
      <div class="cell flex items-center">
        <div class="title u-line-1">{title}</div>
      </div>
    )
    return () => (
      <>
        {info.value.uid && (
          <div class={pageStyle.editModal}>
            <div class="QuestionBasic">
              <NCollapse
                accordion
                class="group w-full"
                arrow-placement="right"
                default-expanded-names={['common']}
              >
                <NCollapseItem
                  name="common"
                  v-slots={{
                    header: () => h(commonHeader('常见属性')),
                    default: () => (
                      <CommonDefault
                        v-model={info.value.commonForm}
                        onUpdate:modelValue={handEmitSave}
                      />
                    )
                  }}
                />
                {slots['default']?.({ info: info.value, handOptions, handSetting })}
                {info.value.formItem && (
                  <NCollapseItem
                    name="formItem"
                    v-slots={{
                      header: () => h(commonHeader('formItem属性')),
                      default: () => (
                        <FormItemDefault
                          v-model={info.value.formItem}
                          onSetting={handSetting}
                          onUpdate:modelValue={handEmitSave}
                        />
                      )
                    }}
                  />
                )}
                {curren.value.length > 1 && info.value.ColLayoutForm && (
                  <NCollapseItem
                    name="colInfo"
                    v-slots={{
                      header: () => h(commonHeader('Col设置')),
                      default: () => (
                        <ColDefault
                          v-model={info.value.ColLayoutForm}
                          onDesc={handDesc}
                          onSetting={handSetting}
                          onUpdate:modelValue={handEmitSave}
                        />
                      )
                    }}
                  />
                )}
              </NCollapse>
              <NCollapse
                class="group mt12 pt12 w-full"
                style={{ borderTop: '1px solid #f2f2f2' }}
                arrow-placement="right"
              >
                <NCollapseItem
                  name="showParams"
                  v-slots={{
                    header: () => h(commonHeader('展示条件')),
                    default: () => (
                      <ShowParamsDefault
                        v-model={info.value.commonForm.showParams}
                        onUpdate:modelValue={handEmitSave}
                      />
                    )
                  }}
                />
              </NCollapse>
            </div>
            <CodeEdit ref={editRef} onSave={codeChange} onDesc={handDesc} />
            {AsyncComponent.value &&
              h(AsyncComponent.value, {
                ref: descRef,
                onLoaded: handLoaded
              })}
          </div>
        )}
      </>
    )
  }
})
